package cn.flying.cloud.oauth.server.configuration.token;

import javax.annotation.Resource;

import java.util.HashMap;
import java.util.Map;

import org.springframework.security.oauth2.common.DefaultOAuth2AccessToken;
import org.springframework.security.oauth2.common.OAuth2AccessToken;
import org.springframework.security.oauth2.provider.OAuth2Authentication;
import org.springframework.security.oauth2.provider.token.TokenEnhancer;
import org.springframework.stereotype.Component;

import com.alibaba.fastjson2.JSON;

import cn.flying.cloud.base.common.constants.Constants;
import cn.flying.cloud.base.redis.service.RedisService;
import cn.flying.cloud.oauth.server.configuration.details.UserDetail;

/**
 * JWT内容增强器
 * 如果你想往JWT中添加自定义信息的话，比如说登录用户的ID，可以自己实现TokenEnhancer接口；
 *
 * @author: admin
 * @date: 2023年06月25日 23:28
 * @version: 1.0
 */
@Component
public class JwtTokenEnhancer implements TokenEnhancer {

    @Resource
    private RedisService redisService;

    /**
     * 配置jwt增加额外信息
     *
     * @param accessToken
     * @param authentication
     * @return
     */
    @Override
    public OAuth2AccessToken enhance(OAuth2AccessToken accessToken, OAuth2Authentication authentication) {
        UserDetail userDetail = (UserDetail) authentication.getPrincipal();

        /**
         * 系统用户按钮权限标识数据量多存放至redis
         *
         * key:AUTH:USER_PERMS:10001
         * value:['sys:user:add',...]
         */
//        redisService.set("AUTH:USER_PERMS:" + userDetail.getUserId(), userDetail.getAuthorities());

        // 这里只缓存认证的UserDetail
        String jwtId = accessToken.getValue();
        String tokenKey = Constants.ACCESS_TOKEN + ":" + jwtId;
        redisService.set(tokenKey, JSON.toJSONString(userDetail), (long) accessToken.getExpiresIn() * 1000);

        Map<String, Object> map = new HashMap<>();
        Map<String, Object> info = new HashMap<>();
        map.put("userInfo", info);
        //把用户信息设置到JWT中
        info.put("tenantId", userDetail.getTenantId());
        info.put("userId", userDetail.getUserId());
        info.put("userName", userDetail.getUsername());
        info.put("avatar", userDetail.getAvatar());
//        info.put("orgId", userDetail.getOrgId());
//        info.put("orgName", userDetail.getOrgName());
        ((DefaultOAuth2AccessToken) accessToken).setAdditionalInformation(map);
        return accessToken;
    }
}
